<?php
// @formatter:off
/**
 * @file WCTag.php
 * @author Alejandro Dario Simi
 * @date $Date: 2013-06-16 19:41:09 +0000 (Sun, 16 Jun 2013) $
 *
 * $Id: WCTag.php 72 2013-06-16 19:41:09Z daemonraco@gmail.com $
 * $URL: http://wcomix.googlecode.com/svn/tags/wcomix-1.0-BETA1/includes/representations/WCTag.php $
 */
// @formatter:on

/**
 * @class WCTag
 */
class WCTag extends WCGTableRepresentation implements WCPreviews {
	public static $PreviewsSeparator = "|";
	public static $PreviewsMaxLength = 640;

	protected $_PropertiesReadOnly = array(
		"id",
		"group"
	);
	protected $_PropertiesBoolean = array(
		"valid_preview",
		"indexed"
	);
	protected $_PropertiesPrefix = "tag_";
	protected $_PropertiesTable = "tags";

	/**
	 * @var WCTagsHolder
	 */
	protected $_holder = null;
	/**
	 * @var bool
	 */
	protected $_special = false;

	public function __construct() {
		parent::__construct();

		global $wcTagsHolder;
		$this->_holder = $wcTagsHolder;
	}
	public function __destruct() {
	}
	//
	// Public methods
	public function add(WCComic &$comic) {
		$out = $this->specialChecks();

		if($out && !$this->has($comic)) {
			$out = false;

			$stmt = null;
			$stmtId = __CLASS__."::".__FUNCTION__;
			if($this->_db->has($stmtId)) {
				$stmt = $this->_db->get($stmtId);
			} else {
				$query = "insert\n";
				$query .= "        into {$this->_dbprefix}tag_members (\n";
				$query .= "                mem_tag, mem_comic, mem_group, mem_added)\n";
				$query .= "        values (:id, :comic, :group, sysdate())";
				$stmt = $this->_db->prepare($stmtId, $query);
			}

			$params = array(
				":id" => $this->id,
				":group" => $this->group,
				":comic" => $comic->id
			);

			if($stmt->execute($params)) {
				global $wcPageCache;

				$wcPageCache->invalidateByTag($this);
				$wcPageCache->invalidateByComic($comic);
				$this->valid_preview = false;
				$this->count++;
				$out = true;
			}
		}

		return $out;
	}
	public function addDirectory(WCDirectory &$directory) {
		$out = $this->specialChecks();

		if($out) {
			global $wcPageCache;
			$wcPageCache->invalidateByDirectory($directory);
			foreach($directory->membersFull() as $comic) {
				$this->add($comic);
			}
		}

		return $out;
	}
	public function addTag(WCTag &$tag) {
		$out = $this->specialChecks();

		if($out) {
			global $wcPageCache;
			$wcPageCache->invalidateByTag($tag);
			foreach($tag->membersFull() as $comic) {
				$this->add($comic);
			}
		}

		return $out;
	}
	public function count() {
		return $this->count;
	}
	public function generatePreviews() {
		$out = false;

		global $wcPageCache;
		global $wcDefaults;

		$previews = array();

		$comics = $this->membersFull();
		$comicCount = count($comics);

		$this->count = $comicCount;

		if($comicCount > 0) {
			$comicCount = $comicCount > 10 ? 10 : $comicCount;

			if($comicCount > 1) {
				foreach(array_rand($comics,$comicCount) as $id) {
					$previews[] = $comics[$id]->previewUri();
				}
			} else {
				$previews[] = $comics[0]->previewUri();
			}

			foreach($previews as $key => $value) {
				if($value == $wcDefaults['preview']) {
					unset($previews[$key]);
				}
			}

			$count = count($previews);
			if($count && $count == $comicCount) {
				$this->previews = implode(self::$PreviewsSeparator, $previews);
				$this->valid_preview = true;
				$out = true;
			}
		}

		return $out;
	}
	public function has(WCComic &$comic) {
		$found = false;

		$params = array(
			":group" => $this->group,
			":tag" => $this->id,
			":comic" => $comic->id
		);

		$stmt = null;
		$stmtId = __CLASS__."::".__FUNCTION__;
		if($this->_db->has($stmtId)) {
			$stmt = $this->_db->get($stmtId);
		} else {
			$query = "select  1\n";
			$query .= "from    {$this->_dbprefix}tag_members\n";
			$query .= "where   mem_tag   = :tag\n";
			$query .= " and    mem_group = :group\n";
			$query .= " and    mem_comic = :comic";

			$stmt = $this->_db->prepare($stmtId, $query);
		}

		if($stmt->execute($params) && $stmt->rowCount() > 0) {
			$found = true;
		}

		return $found;
	}
	public function hasPreview() {
		return $this->hasPreviews();
	}
	public function hasPreviews() {
		return ($this->previews != "");
	}
	public function isSpecial() {
		return $this->_special;
	}
	public function load($id, WCGroup &$group) {
		$this->_ok = false;
		$this->_special = false;

		parent::load($id, $group);

		if($this->ok()) {
			global $wcSpecialTags;

			$this->_info["tag_previews"] = $this->_info["tag_previews"] ? $this->_info["tag_previews"] : false;
			$this->_special = in_array($this->name, $wcSpecialTags);
		}

		return $this->ok();
	}
	/**
	 * @return multitype:integer Returns all comic members ids.
	 */
	public function members() {
		$out = array();

		if($this->ok()) {
			$query = "select  *\n";
			$query .= "from    {$this->_dbprefix}tag_members\n";
			$query .= "                inner join {$this->_dbprefix}comics\n";
			$query .= "                        on(mem_comic = cmc_id and mem_group = cmc_group)\n";
			$query .= "where   mem_tag   = :tag\n";
			$query .= " and    mem_group = :group\n";

			$params = array(
				":group" => $this->group,
				":tag" => $this->id
			);

			$stmt = $this->_db->prepare(__CLASS__."::".__FUNCTION__, $query);

			if($stmt->execute($params)) {
				foreach($stmt->fetchAll() as $row) {
					$out[] = $row["mem_comic"];
				}
			}
		}

		return $out;
	}
	/**
	 * @return multitype:WCComic Returns all comic members a WCComic objects.
	 */
	public function membersFull() {
		$out = array();

		foreach($this->members() as $comic) {
			global $wcComicsHolder;

			$aux = $wcComicsHolder->item($comic, $this->_group);
			if($aux && $aux->ok()) {
				$out[] = $aux;
			}
		}

		return $out;
	}
	public function name() {
		return $this->name;
	}
	public function preview() {
		if($this->previews) {
			$list = $this->previews();
			return array_shift($list);
		} else {
			return "";
		}
	}
	public function previews() {
		if($this->previews) {
			return explode(WCTag::$PreviewsSeparator, $this->previews);
		} else {
			return array();
		}
	}
	public function remove() {
		foreach($this->membersFull() as $comic) {
			$this->removeComic($comic);
		}
		return parent::remove();
	}
	public function removeComic(WCComic &$comic) {
		$out = $this->specialChecks();

		if($out) {
			$out = false;

			$query = "delete from	{$this->_dbprefix}tag_members\n";
			$query .= "where		mem_tag   = :tag\n";
			$query .= " and		mem_group = :group\n";
			$query .= " and		mem_comic = :comic";
			$stmt = $this->_db->prepare(__CLASS__."::".__FUNCTION__."[1]", $query);

			$params = array(
				":tag" => $this->id,
				":group" => $this->group,
				":comic" => $comic->id
			);

			if($stmt->execute($params) && $stmt->rowCount() > 0) {
				global $wcPageCache;

				$wcPageCache->invalidateByTag($this);
				$wcPageCache->invalidateByComic($comic);
				$this->valid_preview = false;
				$this->count--;
				$out = true;
			}
		}

		return $out;
	}
	public function removeDirectory(WCDirectory &$directory) {
		$out = $this->specialChecks();

		if($out) {
			global $wcPageCache;
			$wcPageCache->invalidateByDirectory($directory);
			foreach($directory->membersFull() as $comic) {
				$this->removeComic($comic);
			}
		}

		return $out;
	}
	public function removeTag(WCTag &$tag) {
		$out = $this->specialChecks();

		if($out) {
			global $wcPageCache;
			$wcPageCache->invalidateByTag($tag);
			foreach($tag->membersFull() as $comic) {
				$this->removeComic($comic);
			}
		}

		return $out;
	}
	public function removeAll() {
		$out = $this->specialChecks();

		if($out) {
			$out = false;

			global $wcPageCache;
			$wcPageCache->invalidateByTag($this);

			$query = "delete from	{$this->_dbprefix}tag_members\n";
			$query .= "where		mem_group = :group\n";
			$query .= " and		mem_tag   = :tag";
			$stmt = $this->_db->prepare(__CLASS__."::".__FUNCTION__."[1]", $query);

			$params = array(
				":tag" => $this->id,
				":group" => $this->group
			);

			if($stmt->execute($params)) {
				$this->count = 0;
				$out = true;
			}
		}

		return $out;
	}
	//
	// Protected Methods
	protected function specialChecks() {
		$out = true;

		if($this->_special) {
			global $wcProfile;
			global $wcErrno;
			global $wcError;
			switch($this->name) {
				case WC_SPECIAL_TAG_TRASH:
					if(!$wcProfile->granted(WC_PERM_COMIC_TRASH)) {
						$wcErrno = 403;
						$wcError = "Tag '".WC_SPECIAL_TAG_TRASH."' access denied";
						$out = false;
					}
					break;
			}
		}

		return $out;
	}
	protected function subSet($name, &$value) {
		global $wcPageCache;

		if($wcPageCache) {
			$wcPageCache->invalidateByTag($this);
		}

		if($name == "name") {
			$this->indexed = false;
		}

		return true;
	}
	//
	// Public Class Methods
	public static function IdSort($a, $b) {
		return $a->id > $b->id;
	}
	public static function NameSort($a, $b) {
		return $a->name > $b->name;
	}
}
?>